/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable no-constant-condition */
import { useEffect, useRef, useState } from 'react';
import { Button, Input, Popconfirm, message } from 'antd';
import {
  BorderOutlined,
  DeleteOutlined,
  SendOutlined,
} from '@ant-design/icons';
import { useChatId, useSubmit } from './hoosk';
import ChatListComp from '@src/components/ChatList';
import { IChatItem } from '@src/types/chat';
import { useParams } from 'react-router';
import {
  createMessage,
  createNewChat,
  deleteMessage,
  formatHistoryMessage,
  getChatList,
  getCurChatSession,
  getSelectedChatId,
  updateChatItemByKey,
  updateChatMessage,
  updateSelectedChatID,
} from '@src/utils/chat';
import ChatMessage from '@src/components/ChatMessage';
import { checkAuth } from '@src/utils/checkAuth';
import { useUserInfo } from '@src/store/user/hooks';
import { useChatState } from '@src/store/chat/hooks';
import { useChatRouter } from '@src/hooks/router';

const { TextArea } = Input;

// 聊天组件
const Chat: React.FC<any> = () => {
  const [question, setQuestion] = useState('');
  const { loading, submit, abort } = useSubmit(); // 提交问题
  const messagesEndRef = useRef<any>(null);
  const routeParams = useParams<{ chatId: string }>();
  const userInfo = useUserInfo();
  // 更新路由
  const updateRouter = useChatRouter();
  const [selectedChatId, setSelectedChatId] = useChatId();
  const [curChatItem, setCurChatItem] = useChatState('curChatItem');

  // 更改会话窗口
  useEffect(() => {
    const { chatId } = routeParams;

    // 没有chatId就从缓存中取
    if (!chatId) {
      const storeChatId = getSelectedChatId() || getChatList()?.[0]?.chatId;
      if (storeChatId) {
        updateSelectChat(storeChatId);
        updateRouter(storeChatId);
        scorllToBottom();
      } else {
        // 没找到就清空
        updateSelectChat('', true);
      }
      return;
    }

    updateSelectChat(chatId);
    scorllToBottom();
  }, [routeParams.chatId]);

  // 更新当前选中的会话
  const updateSelectChat = (chatId: string, reset = false) => {
    updateSelectedChatID(reset ? '' : chatId);
    // 更新redux
    setSelectedChatId(reset ? '' : chatId);
    setCurChatItem((reset ? {} : getCurChatSession(chatId)) as IChatItem);
  };

  // 持续获取流式信息
  const onMessageChange = (answerInfo: string, isError?: boolean) => {
    const chatItem = updateChatMessage(
      selectedChatId.current, // 这里用ref保证每次拿到的是新的slectedId
      answerInfo,
      {
        isError,
      },
    );
    setCurChatItem(chatItem);
  };

  // 滚动到底部
  const scorllToBottom = () => {
    setTimeout(() => {
      if (!messagesEndRef.current?.scrollTop) {
        return;
      }
      messagesEndRef.current.scrollTop = messagesEndRef?.current.scrollHeight;
    }, 10);
  };

  // 获取答案
  const getAnswer = () => {
    // 提交前先校验
    if (loading) {
      message.warning('提交太快了～请等智能助手回答完再提交');
      return;
    }

    if (!question) {
      message.warning('请先向智能助手提出您的问题');
      return;
    }

    let chatId = selectedChatId.current;
    // 没有会话id的情况需要新建会话信息
    if (!selectedChatId.current) {
      const curSession = createNewChat(question);
      chatId = curSession.chatId;
      updateSelectChat(chatId);
      updateRouter(curSession.chatId);
    }

    // 更新消息
    setCurChatItem(
      updateChatItemByKey(chatId, 'messages', [
        ...(curChatItem.messages || []),
        createMessage(question, 'user'),
        createMessage('', 'assistant'),
      ]).curChatItem,
    );

    scorllToBottom();
    submit(
      question,
      formatHistoryMessage(selectedChatId.current, 7),
      onMessageChange,
    );
    setQuestion('');
  };

  // 清空聊天
  const clearMessage = () => {
    // 更新消息
    const { curChatItem: chatItem } = updateChatItemByKey(
      selectedChatId.current,
      'messages',
      [],
    );
    setCurChatItem(chatItem);
  };

  // 重新获取信息
  const reGenerate = (index: number) => {
    const curChatItem = deleteMessage(index, selectedChatId.current, 0);
    // 更新消息
    setCurChatItem(
      updateChatItemByKey(selectedChatId.current, 'messages', [
        ...(curChatItem.messages || []),
        createMessage('', 'assistant'),
      ]).curChatItem,
    );

    scorllToBottom();
    submit(
      curChatItem.messages?.[curChatItem.messages.length - 1]?.content || '',
      formatHistoryMessage(selectedChatId.current, 7),
      onMessageChange,
    );
  };

  // 按下回车键
  const onPressEnter = (e: React.KeyboardEvent<HTMLTextAreaElement> & any) => {
    if (!e.shiftKey && e.keyCode == 13) {
      // 只按enter没有按shift的情况下就直接发送文字
      getAnswer();
      e.cancelBubble = true; //ie阻止冒泡行为
      e.stopPropagation(); //Firefox阻止冒泡行为
      e.preventDefault(); //取消事件的默认动作*换行
    }
  };

  return (
    <div className='h-full bg-smart-gray px-3'>
      <div className='bg-white flex rounded-xl shadow-xl w-full h-full'>
        <ChatListComp />
        <div className='w-full bg-chat-logo h-full overflow-hidden'>
          <div className='h-full w-full flex flex-col items-center'>
            {/* 消息展示框 */}
            <div
              ref={messagesEndRef}
              className='w-full overflow-scroll max-h-[87%] h-[87%] flex flex-col items-center'>
              <ChatMessage chatItem={curChatItem} reGenerate={reGenerate} />
            </div>
            {/* 底部对话框 */}
            <div className='w-[65%] mt-7 flex justify-start items-center'>
              {loading ? (
                <Button
                  className='h-[49px]'
                  onClick={abort}
                  icon={<BorderOutlined />}>
                  停止生成
                </Button>
              ) : (
                !!curChatItem?.messages?.length && (
                  <Popconfirm
                    title='是否要清空聊天'
                    onConfirm={clearMessage}
                    okText='是'
                    cancelText='否'>
                    <Button className='h-[49px]' icon={<DeleteOutlined />}>
                      清空内容
                    </Button>
                  </Popconfirm>
                )
              )}
              <div className='mx-2 w-full bg-white shadow-[0_0_10px_rgba(0,0,0,0.10)] relative'>
                <TextArea
                  placeholder='请输入一条消息，shift+enter换行，enter发送'
                  className='m-0 h-full resize-none bg-white py-4 px-6 pr-12 text-black text-14 font-medium'
                  style={{
                    resize: 'none',
                    height: '90px',
                    lineHeight: '15px',
                  }}
                  onPressEnter={checkAuth(onPressEnter, userInfo)}
                  value={question}
                  onChange={(e) => setQuestion(e.target.value)}
                  autoSize={{ minRows: 1, maxRows: 4 }}
                />
                <Button
                  className='absolute right-4 bottom-2 rounded-sm p-1 text-neutral-800'
                  type='text'
                  size='middle'
                  icon={<SendOutlined style={{ color: '#8e8e8e' }} />}
                  onClick={checkAuth(getAnswer, userInfo)}
                  loading={loading}
                />
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Chat;
